package com.jebel.framwork.common.util;

import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;


public class ImageUtil {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    public static void main(String[] args) {
//        String path = "http://patiencecats.com/ueditor/php/upload/image/20180312/1520829763554937.jpg";
//        ImageUtil.downFile(path,"E:/22.jpg");
        //ImageUtil.commpressPicForScale("E:/MSTX_17114558511_14.jpg","E:/1.jpg", 100, 0.8); // 图片小于1000kb
//        commpressPicForScale("C:\\Users\\bianjie\\Desktop\\照片\\20201103F.jpg","C:\\Users\\bianjie\\Desktop\\照片\\20201103FT.jpg",400,0.5,200,100);
        try {
//            while (true) {
            long a1 = System.currentTimeMillis();
            commpressPicForScale("C:\\Users\\bianjie\\Desktop\\照片\\ZM_BOSS100108520190822084004773185_Z.jpg", "C:\\Users\\bianjie\\Desktop\\照片\\ZM_BOSS100108520190822084004773185_ZZ.jpg", 150, 0.4);
//                commpressPicForScale("C:\\Users\\bianjie\\Desktop\\照片\\aaa.jpg", "C:\\Users\\bianjie\\Desktop\\照片\\aaa1.jpg", 100, 0.5);
//                commpressPicForScale("C:\\Users\\bianjie\\Desktop\\照片\\xxx.jpg","C:\\Users\\bianjie\\Desktop\\照片\\xxx2.jpg",100,0.5);
//                commpressPicForScale("C:\\Users\\bianjie\\Desktop\\照片\\Z.jpg","C:\\Users\\bianjie\\Desktop\\照片\\ZA.jpg",150,0.4);
//                commpressPicForScale2("C:\\Users\\bianjie\\Desktop\\照片\\1576485788544.jpg","C:\\Users\\bianjie\\Desktop\\照片\\1576485788544X.jpg",100,0.5);
            long a2 = System.currentTimeMillis();
            System.out.println(a2 - a1);
//                Thread.sleep(1000);
//            }
        } catch (Exception e) {

        }

    }

    /**
     * 根据指定精度压缩图片(原图片大小)
     *
     * @param srcPath    源图片地址
     * @param desPath    目标图片地址
     * @param targetSize 指定图片大小，单位kb
     * @param accuracy   精度，递归压缩的比率，建议小于0.9
     * @return 目标文件路径
     */
    public static String commpressPicForScale(String srcPath, String desPath, long targetSize, double accuracy) {
        try {
            if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(desPath)) {
                return null;
            }
            File srcFile = new File(srcPath);
            if (!srcFile.exists()) {
                return null;
            }
            long srcFileSize = srcFile.length() / 1024;
            logger.info("源图片：{},大小：{} kb", srcPath, srcFileSize);
            if (targetSize >= srcFileSize) {
                logger.info("无需压缩：源大小{}kb,目标大小：{} kb", srcFileSize, targetSize);
                //无需压缩,直接输出到目录
                Thumbnails.of(srcFile).scale(1f).toFile(desPath);
                return desPath;
            }
            commpressPicCycle2(srcPath, desPath, targetSize, accuracy);
            File desFile = new File(desPath);
            logger.info("目标图片：{},大小：{} kb", desPath, desFile.length() / 1024);
            return desPath;
        } catch (Exception e) {
            logger.error("照片压缩失败:{}", e);
            e.printStackTrace();
            return null;
        }
    }

    private static void commpressPicCycle2(String srcPath, String targetPath, long desFileSize, double accuracy) throws IOException {
        File srcFile = new File(srcPath);
        System.out.println("size:" + srcFile.length());
//        if (srcFile.length() <= desFileSize * 1024) {
//            return;
//        }
        while (srcFile.length() >= desFileSize * 1024) {
            // 计算宽高
            BufferedImage bim = ImageIO.read(srcFile);
            bim.flush();
            int desWidth = new BigDecimal(bim.getWidth()).multiply(
                    new BigDecimal(accuracy)).intValue();
            int desHeight = new BigDecimal(bim.getHeight()).multiply(
                    new BigDecimal(accuracy)).intValue();
            Thumbnails.of(srcFile).size(desWidth, desHeight).outputQuality(accuracy).toFile(targetPath);
            srcFile = new File(targetPath);
        }
    }

    private static void commpressPicCycle(String srcPath, String targetPath, long desFileSize, double accuracy) throws IOException {
        File srcFile = new File(srcPath);
        System.out.println("size:" + srcFile.length());
        if (srcFile.length() <= desFileSize * 1024) {
            return;
        }

        // 计算宽高
        BufferedImage bim = ImageIO.read(srcFile);
        bim.flush();
        int desWidth = new BigDecimal(bim.getWidth()).multiply(
                new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(bim.getHeight()).multiply(
                new BigDecimal(accuracy)).intValue();
        Thumbnails.of(srcFile).size(desWidth, desHeight).outputQuality(accuracy).toFile(targetPath);
        //目标文件重复压缩
        commpressPicCycle(targetPath, targetPath, desFileSize, accuracy);
    }


    public static String downFile(String sourceUrl, String targetPath) {
        logger.info("downFile accept:sourceUrl={},targetPath={}", sourceUrl, targetPath);
        if (StringUtil.isEmpty(sourceUrl) || StringUtil.isEmpty(targetPath)) {
            return null;
        }

        URL url = null;

        //从网络上下载一张图片
        InputStream inputStream = null;
        OutputStream outputStream = null;
        //建立一个网络链接
        HttpURLConnection con = null;
        try {
            url = new URL(sourceUrl);
            con = (HttpURLConnection) url.openConnection();
            inputStream = con.getInputStream();
            File file = new File(targetPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            outputStream = new FileOutputStream(file);
            int n = -1;
            byte b[] = new byte[1024];
            while ((n = inputStream.read(b)) != -1) {
                outputStream.write(b, 0, n);
            }
            outputStream.flush();
            return targetPath;
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e1) {
                logger.error(e1.getMessage());
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        return null;
    }
}